package com.unittec.zk.provider.interceptor;

import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.unittec.zk.provider.common.JwtTokenUtil;
import com.unittec.zk.provider.common.Md5;
import com.unittec.zk.provider.common.ServiceFuncUtils;
import com.unittec.zk.provider.common.WebUtils;
import com.unittec.zk.provider.scope.GlobalScope;
import com.unittec.zk.provider.scope.ThreadLocalScope;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.google.common.collect.Lists;
import com.unittec.zk.provider.ApplicationContextProvider;
import com.unittec.zk.provider.log.Log;
import com.unittec.zk.sdk.root.common.FieldConstants;

/**
 * 获取请求的用户信息
 *
 * @author wuxinwei
 */

public class ProviderRootInterceptor implements HandlerInterceptor {

    Log log;

    private static final List<String> IGORE_METHOD_AUTH =
        Lists.newArrayList("/10000", "10004", "/101513", "/102016", "/102023", "/101525");
    private static final List<String> NOT_INTERCEPT_METHOD_AUTH =
        Lists.newArrayList("/app/", "/camunda", "/app/welcome/", "/lib/", "/api/");
    /**
     * 系统主动发起的方法，不用记录日志
     */
    private static final List<String> igore_method_log =
        Lists.newArrayList("/10000", "/102015", "/102016", "/103001", "/103002");

    public ProviderRootInterceptor() {
        log = ApplicationContextProvider.getBean(Log.class);
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {
        boolean ret = true;

        String path = request.getServletPath();

        String tenantId = null;
        String appId = null;
        String appCode = null;
        String requestId = null;
        String loginUser = null;
        String loginUserName = null;

        if (null != request.getHeader(FieldConstants.TENANT_ID)) {
            tenantId = request.getHeader(FieldConstants.TENANT_ID);
        }

        if (null != request.getHeader(FieldConstants.LOGIN_USER)) {
            loginUser = request.getHeader(FieldConstants.LOGIN_USER);
        }
        if (null != request.getHeader(FieldConstants.LOGIN_USER_NAME)) {
            loginUserName = request.getHeader(FieldConstants.LOGIN_USER_NAME);
        }
        if (null != request.getHeader(FieldConstants.APP_ID)) {
            appId = request.getHeader(FieldConstants.APP_ID);
        }

        if (null != request.getHeader(FieldConstants.REQUEST_ID)) {
            requestId = request.getHeader(FieldConstants.REQUEST_ID);
        }

        if (null != request.getHeader(FieldConstants.APP_CODE)) {
            appCode = request.getHeader(FieldConstants.APP_CODE);
        }
        String ip = WebUtils.getIpAddress(request);
        String token = request.getHeader(FieldConstants.REQ_AUTHORIZATION);
        ThreadLocalScope.setAuthData(requestId, token, appId, tenantId, ip, loginUser, appCode, loginUserName);
        String logmsg = "";
        if (!igore_method_log.contains(request.getRequestURI())) {
            logmsg = String.format("preHandle url=[%s] requestId=[%s] appId=[%s] tenantId=[%s] ",
                request.getRequestURI(), requestId, appId, tenantId);
            log.sysInfoLog("preHandle", logmsg);
        }
        String sysRequestSource = request.getHeader(FieldConstants.SYS_REQUEST_SOURCE);
        // 如果系统请求标识 符合 就不验证下面的逻辑
        if (StringUtils.isNotBlank(sysRequestSource)
            && Md5.getMd5(FieldConstants.SYS_REQUEST_SOURCE_ID).equalsIgnoreCase(sysRequestSource)) {
            return true;
        }
        //
        if (path.startsWith("/swagger") || path.startsWith("/webjars") || path.startsWith("/v2/api")
            || path.startsWith("/v2/api-docs") || path.startsWith("/doc") || path.startsWith("/error")
            || path.startsWith("/favicon.ico")) {
            return true;
        }
        //
        String requestURI = request.getRequestURI();
        if (IGORE_METHOD_AUTH.contains(requestURI)) {
            return ret;
        }
        if (ServiceFuncUtils.isSysFun(requestURI.substring(1))) {
            return ret;
        }
        for (String s : NOT_INTERCEPT_METHOD_AUTH) {
            if (requestURI.startsWith(s)) {
                return ret;
            }
        }
        if ("/".equals(requestURI)) {
            return ret;
        }
        if (null != token) {
            try {
                // 将token存放在全局和线程变量内，用于后续的远程方法调用做鉴权使用
                if (token.length() > 20 && token.contains(FieldConstants.REQ_BEARER)) {
                    token = token.substring(7);
                    if (null != appId) {
                        GlobalScope.setToken(appId, token);
                    }
                    JwtTokenUtil.verifyToken(token);
                } else {
                    response.setStatus(HttpStatus.UNAUTHORIZED.value());
                    ret = false;
                }
            } catch (Exception e) {
                log.sysErrLog("verifyToken", token + " " + logmsg + e.toString(), e);
                response.setStatus(HttpStatus.UNAUTHORIZED.value());
                ret = false;
            }
        } else {
            response.setStatus(HttpStatus.UNAUTHORIZED.value());

            ret = false;
        }

        return ret;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
        ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
        throws Exception {

    }
}
